#include "cardstack.h"
#include <QDragEnterEvent>
#include <QMimeData>
#include <QVBoxLayout>
#include <QDataStream>

CardStack::CardStack(QWidget* parent)
    : QWidget(parent), m_spacing(30)
{
    setAcceptDrops(true);
}

void CardStack::addCard(Card* card) {
    m_cards.append(card);
    card->setParent(this);
    card->show();
    updateLayout();
}

void CardStack::removeCard(Card* card) {
    m_cards.removeOne(card);
    card->setParent(nullptr);
    updateLayout();
}

QVector<Card*> CardStack::cards() const {
    return m_cards;
}

void CardStack::clear() {
    for (Card* card : m_cards) {
        card->deleteLater();
    }
    m_cards.clear();
}

void CardStack::setSpacing(int spacing) {
    m_spacing = spacing;
    updateLayout();
}

void CardStack::flipTopCard() {
    if (!m_cards.isEmpty()) {
        m_cards.last()->setFaceUp(true);
    }
}

void CardStack::updateLayout() {
    int y = 0;
    for (Card* card : std::as_const(m_cards)) {
        card->move(0, y);
        y += m_spacing;
    }
    update();
}

void CardStack::dragEnterEvent(QDragEnterEvent* event) {
    if (event->mimeData()->hasFormat("text/card-group")) {
        event->acceptProposedAction();
    }
}

void CardStack::dragMoveEvent(QDragMoveEvent* event) {
    event->acceptProposedAction();
}

void CardStack::dropEvent(QDropEvent* event) {
    QByteArray data = event->mimeData()->data("text/card-group");
    QDataStream stream(&data, QIODevice::ReadOnly);
    quintptr ptrVal;
    stream >> ptrVal;
    Card* card = reinterpret_cast<Card*>(ptrVal);

    if (!card || card->parent() == this)
        return;

    CardStack* oldStack = qobject_cast<CardStack*>(card->parent());
    if (!oldStack)
        return;

    // 确认拖动的是一串连续的可见卡牌
    QVector<Card*> cardsToMove;
    QVector<Card*> oldCards = oldStack->cards();
    int index = oldCards.indexOf(card);
    if (index == -1)
        return;

    for (int i = index; i < oldCards.size(); ++i) {
        if (!oldCards[i]->isFaceUp())
            return;
        if (!cardsToMove.isEmpty() &&
            oldCards[i]->value() != cardsToMove.last()->value() - 1)
            return;
        cardsToMove.append(oldCards[i]);
    }

    // 目标栈顶部卡牌检查是否可以接
    if (!m_cards.isEmpty()) {
        Card* top = m_cards.last();
        if (cardsToMove.first()->value() != top->value() - 1)
            return;
    }

    for (Card* c : cardsToMove) {
        oldStack->removeCard(c);
        addCard(c);
    }

    oldStack->flipTopCard();
    event->acceptProposedAction();
}
